<template>
  <div class="container flowChartContainer">
    <!--  工具  -->
    <div id="toolbar">
      <el-button
          size="mini"
          type="primary"
          @click="
          $refs.chart.add({
            id: +new Date(),
            x: 400,
            y: 100,
            name: '标题',
            type: '普通结点',
            approvers: []
          })
        "
      >新增</el-button
      >
      <el-button size="mini" type="primary" @click="$refs.chart.editCurrent()"
      >编辑</el-button
      >
      <el-button size="mini" type="danger" @click="$refs.chart.remove()"
      >删除</el-button
      >
      <el-button size="mini" type="success" @click="$refs.chart.save()"
      >保存</el-button
      >
    </div>
    <flowchart
        :nodes="nodes"
        :connections="connections"
        @editnode="handleEditNode"
        :width="'100%'"
        :height="900"
        :readonly="false"
        @dblclick="handleDblClick"
        @editconnection="handleEditConnection"
        @save="handleChartSave"
        ref="chart"
        :render="render"
    >
    </flowchart>
    <node-dialog
        :visible.sync="nodeDialogVisible"
        :node.sync="nodeForm.target"
    ></node-dialog>
    <connection-dialog
        :visible.sync="connectionDialogVisible"
        :connection.sync="connectionForm.target"
        :operation="connectionForm.operation"
    >
    </connection-dialog>

    <!--   流程图保存弹框   -->
    <el-dialog
        title="流程图信息"
        :visible.sync="flowInfomationAlert"
        width="30%"
    >
      <el-form
          :model="flowForm"
          :rules="rules"
          ref="flowForm"
          label-width="100px"
          class="demo-ruleForm"
      >
        <el-form-item label="流程图名称" prop="processName">
          <el-input v-model="flowForm.processName"></el-input>
        </el-form-item>
        <el-form-item label="备注信息" prop="remark">
          <el-input v-model="flowForm.remark"></el-input>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="flowFormSubmit('flowForm')">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
/* eslint-disable no-unused-vars */
import ConnectionDialog from "./flow/tool/ConnectionDialog";
import NodeDialog from "./flow/tool/NodeDialog";
import Flowchart from "./flow/tool/flowchart/Flowchart";
import * as d3 from "d3";
import { roundTo20 } from "./flow/utils/math";
export default {
  components: {
    ConnectionDialog,
    NodeDialog,
    Flowchart
  },
  data: function() {
    return {
      //保存流程图弹框
      flowInfomationAlert: false,
      nodes: [
        { id: 1, x: 50, y: 220, name: "开始", type: "start" },
        { id: 2, x: 800, y: 220, name: "结束", type: "end" }
      ],
      connections: [],
      nodeForm: { target: null },
      connectionForm: { target: null, operation: null },
      nodeDialogVisible: false,
      connectionDialogVisible: false,
      //传给后台的节点数据
      nodesList: {
        node: [],
        line: []
      },
      flowForm: {
        processName: "",
        remark: "",
        file: ""
      },
      rules: {
        processName: [
          { required: true, message: "请输入流程图名称", trigger: "blur" }
        ]
      }
    };
  },
  async mounted() {},
  methods: {
    handleDblClick(position) {
      this.$refs.chart.add({
        id: +new Date(),
        x: position.x,
        y: position.y,
        name: "标题",
        type: "内容",
        approvers: []
      });
    },
    //保存按钮
    async handleChartSave(nodes, connections) {
      //console.log(nodes,connections)
      this.flowInfomationAlert = true;
      this.nodesList.node = [];
      this.nodesList.line = [];
      this.nodesList.node = nodes;
      this.nodesList.line = connections;
      //console.log(JSON.stringify(this.nodesList))
      this.flowForm.file = JSON.stringify(this.nodesList);
    },
    //流程图确认保存
    flowFormSubmit: function(flowForm) {
      this.$refs[flowForm].validate((valid) => {
        if (valid) {
          this.flowInfomationAlert=false;
          this.$message({
            message:'保存成功，数据请前往控制台查看！',
            type: 'success'});
          console.log(this.flowForm);
        } else {
          return false;
        }
      });
    },
    handleEditNode(node) {
      this.nodeForm.target = node;
      this.nodeDialogVisible = true;
    },
    handleEditConnection(connection) {
      this.connectionForm.target = connection;
      this.connectionDialogVisible = true;
    },
    render: function(g, node, isSelected) {
      node.width = node.width || 120;
      node.height = node.height || 60;
      let borderColor = isSelected ? "#FF7600" : "#bbbbbb";
      if (node.type !== "start" && node.type !== "end") {
        // title
        if (node.id !== 3) {
          g.append("rect")
              .attr("x", node.x)
              .attr("y", node.y)
              .attr("stroke", borderColor)
              .attr("class", "title")
              .style("height", "20px")
              .style("fill", "#f1f3f4")
              .style("stroke-width", "1px")
              .style("width", node.width + "px");
          g.append("text")
              .attr("x", node.x + 4)
              .attr("y", node.y + 15)
              .attr("class", "unselectable")
              .text(() => node.name)
              .each(function wrap() {
                let self = d3.select(this),
                    textLength = self.node().getComputedTextLength(),
                    text = self.text();
                while (textLength > node.width - 2 * 4 && text.length > 0) {
                  text = text.slice(0, -1);
                  self.text(text + "...");
                  textLength = self.node().getComputedTextLength();
                }
              });
        }
      }
      // body
      if (node.id === 3) {
        let body = g.append("ellipse").attr("class", "body");
        body.attr("cx", node.x + node.width / 2);
        body.attr("cy", node.y + node.height / 2);
        body.attr("rx", node.width / 2);
        body.attr("ry", node.height / 2);
        body.style("fill", "white");
        body.style("stroke-width", "1px");
        body.classed(node.type, true);
        body.attr("stroke", borderColor);
      } else {
        let body = g.append("rect").attr("class", "body");
        body
            .style("width", node.width + "px")
            .style("fill", "white")
            .style("stroke-width", "1px");
        if (node.type !== "start" && node.type !== "end") {
          body.attr("x", node.x).attr("y", node.y + 20);
          body.style("height", roundTo20(node.height - 20) + "px");
        } else {
          body
              .attr("x", node.x)
              .attr("y", node.y)
              .classed(node.type, true)
              .attr("rx", 30);
          body.style("height", roundTo20(node.height) + "px");
        }
        body.attr("stroke", borderColor);
      }
      // body text
      let text =
          node.type === "start"
              ? "开始"
              : node.type === "end"
              ? "结束"
              : !node.approvers || node.approvers.length === 0
                  ? "内容"
                  : node.approvers.length > 1
                      ? `${node.approvers[0].name + "..."}`
                      : node.approvers[0].name;
      let bodyTextY;
      if (node.type !== "start" && node.type !== "end") {
        if (node.id === 3) {
          bodyTextY = node.y + 25;
        } else {
          bodyTextY = node.y + 25 + roundTo20(node.height - 20) / 2;
        }
      } else {
        bodyTextY = node.y + 5 + roundTo20(node.height) / 2;
      }
      g.append("text")
          .attr("x", node.x + node.width / 2)
          .attr("y", bodyTextY)
          .attr("class", "unselectable")
          .attr("text-anchor", "middle")
          .text(function() {
            return text;
          })
          .each(function wrap() {
            let self = d3.select(this),
                textLength = self.node().getComputedTextLength(),
                text = self.text();
            while (textLength > node.width - 2 * 4 && text.length > 0) {
              text = text.slice(0, -1);
              self.text(text + "...");
              textLength = self.node().getComputedTextLength();
            }
          });
    }
  }
};
</script>
<style scoped>
#toolbar {
  width: 80%;
  position: absolute;
  margin: 1%;
  z-index: 1;
  text-align: left;
}
.title {
  margin-top: 10px;
  margin-bottom: 0;
}
.subtitle {
  margin-bottom: 10px;
}
#toolbar > button {
  margin-right: 4px;
}
.container {
  width: 98%;
  margin: auto;
}
</style>
